//头文件部分

#include "sle_low_latency.h"

#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include "cmsis_os2.h"
#include "app_init.h"
#include "soc_osal.h"

#include "common_def.h"
#include "pinctrl.h"
#include "uart.h"

#include "securec.h"
#include "sle_device_discovery.h"
#include "sle_errcode.h"

#include "lwip/nettool/misc.h"
#include "lwip/ip4_addr.h"
#include "lwip/netif.h"
#include "lwip/netifapi.h"
#include "lwip/sockets.h"

#include "watchdog.h"
#include "i2c.h"
#include "osal_debug.h"

#include "gpio.h"

#include "adc.h"
#include "adc_porting.h"

#include "sht3x.h"

#if defined(CONFIG_SAMPLE_SUPPORT_SLE_UART_SERVER_1_VS_8)
#include "securec.h"
#include "sle_uart_server.h"
#include "sle_uart_server_adv.h"
#include "sle_device_discovery.h"
#include "sle_errcode.h"
#elif defined(CONFIG_SAMPLE_SUPPORT_SLE_UART_CLIENT_1_VS_8)
#define SLE_UART_TASK_STACK_SIZE            0x600
#include "sle_connection_manager.h"
#include "sle_ssap_client.h"
#include "sle_uart_client.h"
#endif  



//全局变量
char ligBuffer[10]={0};
char humidity[10] = {0};
char temperature[10] = {0};
char soilHum[10]={0};
char send_data[100]={0};
#define VREF 3300.0f // 参考电压（mV）


#define SLE_UART_TASK_PRIO                  28
#define SLE_UART_TASK_DURATION_MS           2000

//UART部分
#define UART_BAUDRATE                      115200
#define UART_DATA_BITS                     3
#define UART_STOP_BITS                     1
#define UART_PARITY_BIT                    0
#define UART_TRANSFER_SIZE                 512
#define CONFIG_UART_INT_WAIT_MS            5

#define UART_TASK_STACK_SIZE               0x1000
#define UART_TASK_DURATION_MS              1000
#define UART_TASK_PRIO                     (osPriority_t)(17)

static uint8_t g_app_uart_int_rx_flag = 0;

static uint8_t g_app_uart_rx_buff[UART_TRANSFER_SIZE] = { 0 };

static uart_buffer_config_t g_app_uart_buffer_config = {
    .rx_buffer = g_app_uart_rx_buff,
    .rx_buffer_size = UART_TRANSFER_SIZE
};

static void uart_init_pin(void)
{
    uapi_pin_set_mode(CONFIG_UART_TXD_PIN, PIN_MODE_1);
    uapi_pin_set_mode(CONFIG_UART_RXD_PIN, PIN_MODE_1);       
}

static void uart_init_config(void)
{
    uart_attr_t attr = {
        .baud_rate = UART_BAUDRATE,
        .data_bits = UART_DATA_BIT_8,
        .stop_bits = UART_STOP_BIT_1,
        .parity = UART_PARITY_NONE
    };

    uart_pin_config_t pin_config = {
        .tx_pin = CONFIG_UART_TXD_PIN,
        .rx_pin = CONFIG_UART_RXD_PIN,
        .cts_pin = PIN_NONE,
        .rts_pin = PIN_NONE
    };
    uapi_uart_deinit(2);
    uapi_uart_init(2, &pin_config, &attr, NULL, &g_app_uart_buffer_config);

}
static void app_uart_write_int_handler(const void *buffer, uint32_t length, const void *params)
{
    unused(params);
    uint8_t *buff = (void *)buffer;
    // for (uint32_t i = 0; i < length; i++) {
    //     osal_printk("uart%d write data[%d] = %d\r\n", CONFIG_SLE_UART_BUS, i, buff[i]);
    // }
    osal_printk("send data:%s\r\n",buff);
    
}
#if defined(CONFIG_SAMPLE_SUPPORT_SLE_UART_SERVER_1_VS_8)
#define SLE_UART_SERVER_DELAY_COUNT         5

#define SLE_UART_TASK_STACK_SIZE            0x1200
#define SLE_ADV_HANDLE_DEFAULT              1
#define SLE_UART_SERVER_MSG_QUEUE_LEN       5
#define SLE_UART_SERVER_MSG_QUEUE_MAX_SIZE  32
#define SLE_UART_SERVER_QUEUE_DELAY         0xFFFFFFFF
#define SLE_UART_SERVER_BUFF_MAX_SIZE       800

#define GATHER_TASK_STACK_SIZE 0x1000
#define GATHER_TASK_PRIO (osPriority_t)(17)



unsigned long g_sle_uart_server_msgqueue_id;
#define SLE_UART_SERVER_LOG                 "[sle uart server]"
static void ssaps_server_read_request_cbk(uint8_t server_id, uint16_t conn_id, ssaps_req_read_cb_t *read_cb_para,
    errcode_t status)
{
    osal_printk("%s ssaps read request cbk callback server_id:%x, conn_id:%x, handle:%x, status:%x\r\n",
        SLE_UART_SERVER_LOG, server_id, conn_id, read_cb_para->handle, status);
}
static void ssaps_server_write_request_cbk(uint8_t server_id, uint16_t conn_id, ssaps_req_write_cb_t *write_cb_para,
    errcode_t status)
{
    osal_printk("%s ssaps write request callback cbk server_id:%x, conn_id:%x, handle:%x, status:%x\r\n",
        SLE_UART_SERVER_LOG, server_id, conn_id, write_cb_para->handle, status);
    if ((write_cb_para->length > 0) && write_cb_para->value) {
        osal_printk("\n sle uart recived data : %s\r\n", write_cb_para->value);
        uapi_uart_write(CONFIG_SLE_UART_BUS, (uint8_t *)write_cb_para->value, write_cb_para->length, 0);
        uapi_uart_write(2, (uint8_t *)write_cb_para->value, write_cb_para->length, 0);
    
    }
}

static void sle_uart_server_read_int_handler(const void *buffer, uint16_t length, bool error)
{
    unused(error);
    if (sle_uart_client_is_connected()) {
    sle_uart_server_send_report_by_handle(buffer, length);
    } else {
        osal_printk("%s sle client is not connected! \r\n", SLE_UART_SERVER_LOG);
    }
}


static void sle_uart_server_create_msgqueue(void)
{
    if (osal_msg_queue_create("sle_uart_server_msgqueue", SLE_UART_SERVER_MSG_QUEUE_LEN, \
        (unsigned long *)&g_sle_uart_server_msgqueue_id, 0, SLE_UART_SERVER_MSG_QUEUE_MAX_SIZE) != OSAL_SUCCESS) {
        osal_printk("^%s sle_uart_server_create_msgqueue message queue create failed!\n", SLE_UART_SERVER_LOG);
    }
}

static void sle_uart_server_delete_msgqueue(void)
{
    osal_msg_queue_delete(g_sle_uart_server_msgqueue_id);
}

static void sle_uart_server_write_msgqueue(uint8_t *buffer_addr, uint16_t buffer_size)
{
    osal_msg_queue_write_copy(g_sle_uart_server_msgqueue_id, (void *)buffer_addr, \
                              (uint32_t)buffer_size, 0);
}

static int32_t sle_uart_server_receive_msgqueue(uint8_t *buffer_addr, uint32_t *buffer_size)
{
    return osal_msg_queue_read_copy(g_sle_uart_server_msgqueue_id, (void *)buffer_addr, \
                                    buffer_size, SLE_UART_SERVER_QUEUE_DELAY);
}
static void sle_uart_server_rx_buf_init(uint8_t *buffer_addr, uint32_t *buffer_size)
{
    *buffer_size = SLE_UART_SERVER_MSG_QUEUE_MAX_SIZE;
    (void)memset_s(buffer_addr, *buffer_size, 0, *buffer_size);
}


static void *sle_uart_server_task(const char *arg)
{
    unused(arg);
    uint8_t rx_buf[SLE_UART_SERVER_MSG_QUEUE_MAX_SIZE] = {0};
    uint32_t rx_length = SLE_UART_SERVER_MSG_QUEUE_MAX_SIZE;
    uint8_t sle_connect_state[] = "sle_dis_connect";

    sle_uart_server_create_msgqueue();
    sle_uart_server_register_msg(sle_uart_server_write_msgqueue);
    sle_uart_server_init(ssaps_server_read_request_cbk, ssaps_server_write_request_cbk);


    /* UART pinmux. */
    uart_init_pin();

    /* UART init config. */
    uart_init_config();

    uapi_uart_unregister_rx_callback(CONFIG_SLE_UART_BUS);
    errcode_t ret = uapi_uart_register_rx_callback(CONFIG_SLE_UART_BUS,
                                                   UART_RX_CONDITION_FULL_OR_IDLE,
                                                   1, sle_uart_server_read_int_handler);
    if (ret != ERRCODE_SUCC) {
        osal_printk("%s Register uart callback fail.[%x]\r\n", SLE_UART_SERVER_LOG, ret);
        return NULL;
    }
    while (1) {
        sle_uart_server_rx_buf_init(rx_buf, &rx_length);
        sle_uart_server_receive_msgqueue(rx_buf, &rx_length);
        if (strncmp((const char *)rx_buf, (const char *)sle_connect_state, sizeof(sle_connect_state)) == 0) {
            ret = sle_start_announce(SLE_ADV_HANDLE_DEFAULT);
            if (ret != ERRCODE_SLE_SUCCESS) {
                osal_printk("%s sle_connect_state_changed_cbk,sle_start_announce fail :%02x\r\n",
                    SLE_UART_SERVER_LOG, ret);
            }
        }
        osal_msleep(SLE_UART_TASK_DURATION_MS);
    }
    sle_uart_server_delete_msgqueue();
    return NULL;
}
#elif defined(CONFIG_SAMPLE_SUPPORT_SLE_UART_CLIENT_1_VS_8)

void sle_uart_notification_cb(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *data,
    errcode_t status)
{
    unused(client_id);
    unused(conn_id);
    unused(status);
    osal_printk("\n sle uart re data : %s\r\n", data->data);
    uapi_uart_write(CONFIG_SLE_UART_BUS, (uint8_t *)(data->data), data->data_len, 0);
    // uapi_uart_write_int(2, (uint8_t *)(data->data), data->data_len, 0,app_uart_write_int_handler);
    uapi_uart_write(2, (uint8_t *)(data->data), data->data_len, 0);


    uint8_t *buff = (uint8_t *)(data->data);
    if (memcpy_s(g_app_uart_rx_buff, data->data_len, buff, data->data_len) != EOK) {
        osal_printk("uart%d int mode data copy fail!\r\n", 2);
        osal_printk("data:%s\r\n",buff);
        return;
    }
    g_app_uart_int_rx_flag = 1;
}

void sle_uart_indication_cb(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *data,
    errcode_t status)
{
    unused(client_id);
    unused(conn_id);
    unused(status);
    osal_printk("\n sle uart 收发 : %s\r\n", data->data);
    uapi_uart_write(CONFIG_SLE_UART_BUS, (uint8_t *)(data->data), data->data_len, 0);
    uapi_uart_write(2, (uint8_t *)(data->data), data->data_len, 0);
    
}

static void sle_uart_client_read_int_handler(const void *buffer, uint16_t length, bool error)
{
    unused(error);

    uint8_t *buff = (uint8_t *)buffer;
    char num_str[2] = {buff[0], '\0'};                                  //把第一个字符当作conn_id
    ssapc_write_param_t *sle_uart_send_param = get_g_sle_uart_send_param();
    uint16_t g_sle_uart_conn_id = atoi(num_str);                            

    osal_printk("\n sle_uart_client_read_int_handler: %d\r\n", g_sle_uart_conn_id);
    sle_uart_send_param->data_len = length - 1;
    sle_uart_send_param->data = (uint8_t *)buffer+1;                    // 调整数据指针，指向 buffer 的第二个字节
    ssapc_write_req(0, g_sle_uart_conn_id, sle_uart_send_param);

    // if (memcpy_s(g_app_uart_rx_buff, sle_uart_send_param->data_len, sle_uart_send_param->data, sle_uart_send_param->data_len) != EOK) {
    //     osal_printk("uart%d 数据拷贝失败!\r\n", CONFIG_SLE_UART_BUS);
    //     osal_printk("data:%s\r\n",buff);
    //     return;
    // }
    // else
    //     osal_printk("copy ok!!!\r\n");
    // g_app_uart_int_rx_flag = 1;

}



// void light_adc_callback(uint8_t ch, uint32_t *buffer, uint32_t length, bool *next) 
// { 
//     UNUSED(next);
//     for (uint32_t i = 0; i < length; i++) {
//         printf("channel: %d, voltage: %dmv\r\n", ch, buffer[i]);
//     } 
// }



static void *sle_uart_client_task(const char *arg)
{
    unused(arg);
    /* UART pinmux. */
    uart_init_pin();

    /* UART init config. */
    uart_init_config();

    uapi_uart_unregister_rx_callback(CONFIG_SLE_UART_BUS);
    errcode_t ret = uapi_uart_register_rx_callback(CONFIG_SLE_UART_BUS,
                                                   UART_RX_CONDITION_FULL_OR_IDLE,
                                                   1, sle_uart_client_read_int_handler);
    sle_uart_client_init(sle_uart_notification_cb, sle_uart_indication_cb);
    
    
    if (ret != ERRCODE_SUCC) {
        osal_printk("Register uart callback fail.");
        return NULL;
    }

    while (1) {
        osal_msleep(UART_TASK_DURATION_MS);

        while (g_app_uart_int_rx_flag != 1) {
            osal_msleep(CONFIG_UART_INT_WAIT_MS);
        }
        g_app_uart_int_rx_flag = 0;
        uapi_uart_write_int(2, g_app_uart_rx_buff, UART_TRANSFER_SIZE, 0,
                                app_uart_write_int_handler);
    }
    return NULL;
}
#endif  /* CONFIG_SAMPLE_SUPPORT_SLE_UART_CLIENT_1_VS_8 */

static void sle_uart_entry(void)
{
    osal_task *task_handle = NULL;
    osal_kthread_lock();
#if defined(CONFIG_SAMPLE_SUPPORT_SLE_UART_SERVER_1_VS_8)
    task_handle = osal_kthread_create((osal_kthread_handler)sle_uart_server_task, 0, "SLEUartServerTask",
                                      SLE_UART_TASK_STACK_SIZE);
#elif defined(CONFIG_SAMPLE_SUPPORT_SLE_UART_CLIENT_1_VS_8)
    task_handle = osal_kthread_create((osal_kthread_handler)sle_uart_client_task, 0, "SLEUartDongleTask",
                                      SLE_UART_TASK_STACK_SIZE);
#endif /* CONFIG_SAMPLE_SUPPORT_SLE_UART_CLIENT_1_VS_8 */
    if (task_handle != NULL) {
        osal_kthread_set_priority(task_handle, SLE_UART_TASK_PRIO);
    }
    osal_kthread_unlock();
}





void light_adc_callback(uint8_t ch, uint32_t *buffer, uint32_t length, bool *next)
{
    UNUSED(next);
    for (uint32_t i = 0; i < length; i++)
    {
        float voltage_mv = buffer[i]; // 获取电压值（单位：mV）

        float lux = (VREF - voltage_mv) / 33.0f;

        // 限制Lux值范围
        if (lux > 1000.0f)
        {
            lux = 1000.0f;
        }
        else if(lux<0.0f)
            lux=0.0f;
        
        sprintf(ligBuffer, "%.2f", lux);
        
    }
}
void soilHum_adc_callback(uint8_t ch, uint32_t *buffer, uint32_t length, bool *next)
{
    UNUSED(next);
    for (uint32_t i = 0; i < length; i++)
    {
        float voltage_mv = buffer[i]; // 获取电压值（单位：mV）

        float lux = voltage_mv / 33.0f;

        // 限制Lux值范围
        if (lux > 1000.0f)
        {
            lux = 1000.0f;
        }
        else if(lux<0.0f)
            lux=0.0f;
        
        sprintf(soilHum, "%.2f", lux);
        
    }
}

#if defined(CONFIG_SAMPLE_SUPPORT_SLE_UART_SERVER_1_VS_8)
static void *gather_task(const char *arg)  
{
    UNUSED(arg);
    osal_printk("开始监测温湿度");

    float temp = 0.0f;
    float humi = 0.0f;
    //开启sht3x
    sht30_Port_Init();

    //光照初始化
    uapi_adc_init(ADC_CLOCK_500KHZ);
    uapi_adc_power_en(AFE_SCAN_MODE_MAX_NUM, true);
    adc_scan_config_t config = {
        .type = 0,
        .freq = 1,
    };


    while (1)
    {
        // 发送开始测量命令
        sht30_start_measurement();
        if (sht30_read_data(&temp, &humi) == 0){
            sprintf(temperature, "%.2f", temp);
            sprintf(humidity, "%.2f", humi);
        }else {
            osal_printk("error");
            osDelay(200);
        }


        //光照
        uapi_adc_auto_scan_ch_enable(ADC_CHANNEL_2, config, light_adc_callback);
        uapi_adc_auto_scan_ch_disable(ADC_CHANNEL_2);
        //土壤
        uapi_adc_auto_scan_ch_enable(ADC_CHANNEL_3, config, soilHum_adc_callback);
        uapi_adc_auto_scan_ch_disable(ADC_CHANNEL_3);
            
        osal_printk("A running\r\n");
        osal_printk("湿度: %s\r\n", humidity);
        osal_printk("温度: %s\r\n", temperature);
        osal_printk("光照: %s\r\n", ligBuffer);
        osal_printk("土壤湿度: %s\r\n", soilHum);
        osal_printk("\r\n");
        osal_printk("\r\n");
        snprintf(send_data, sizeof(send_data), "2,Hum:%s,Tem:%s,Lig:%s,SoilHum:%s,over", humidity, temperature,ligBuffer,soilHum);
        if (sle_uart_client_is_connected()) {
            sle_uart_server_send_report_by_handle((const uint8_t *)send_data, strlen(send_data));
        } else {
            osal_printk("%s 星闪未连接! \r\n", SLE_UART_SERVER_LOG);
        }
        
        osal_msleep(2000);
    }

    return NULL;
}

static void gather_entry(void)
{
    osThreadAttr_t attr;

    attr.name = "gatherTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = GATHER_TASK_STACK_SIZE;
    attr.priority = GATHER_TASK_PRIO;

    if (osThreadNew((osThreadFunc_t)gather_task, NULL, &attr) == NULL)
    {
        osal_printk("Failed to create ADC task.\n");
    }
}



app_run(gather_entry);
#endif
/* Run the sle_uart_entry. */
app_run(sle_uart_entry);